package org.cloud.automatic.queue.service.impl;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.cloud.automatic.constant.BaseConstant;
import org.cloud.automatic.queue.entity.SendQueueWorkerBO;
import org.cloud.automatic.queue.entity.SystemSendQueueBO;
import org.cloud.automatic.queue.listener.SystemSendQueueHelper;
import org.cloud.automatic.queue.service.ClientConfigService;
import org.cloud.automatic.queue.service.SchedulerJobService;
import org.cloud.automatic.queue.service.SendQueueDealService;
import org.cloud.automatic.queue.service.SystemSendQueueBOService;
import org.cloud.automatic.util.SpringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Description: 事务补偿实现
 * @Param: 
 * @return: 
 * @Author: gangzhenga
 * @Date: 2021/7/13 9:58
 */
@Slf4j
@Service("sendQueueDealService")
public class SendQueueDealServiceImpl implements SendQueueDealService {

    @Autowired
    private SystemSendQueueBOService systemSendQueueBOService;

	@Override
    public boolean indepDealWork(SendQueueWorkerBO sendQueueWorkerBO) throws Exception{
        
        SystemSendQueueBO systemSendQueueBO = sendQueueWorkerBO.getData();
        
        try {
            int sendNum = systemSendQueueBO.getSendNum() == null ?  0  :  systemSendQueueBO.getSendNum();
            
            systemSendQueueBO.setSendNum(sendNum +1);
            String bizCode = systemSendQueueBO.getBizCode();
            String bizId = systemSendQueueBO.getBizId();
            
            log.info("===开始事务补偿==={}===", bizId);

            // 设置当前补偿点
            SystemSendQueueHelper.setSystemSendQueueBO(systemSendQueueBO);
            log.info("==补偿队列数据=={}==", JSONObject.toJSONString(systemSendQueueBO));
            
            ClientConfigService clientConfigService = SpringUtil.getBean("clientConfigService");
            if(clientConfigService == null) {
                log.error("【ClientConfigService】缺少必须的实现类");
                throw new Exception("【ClientConfigService】缺少必须的实现类");
            }
            
            String seriveName = clientConfigService.getBeanNameFromConfig(bizCode);
            if(StringUtils.isEmpty(seriveName)) {
                log.error("缺少必须的补偿点配置, 补偿点code：{}", bizCode);
                throw new Exception("缺少必须的补偿点配置");
            }

            SchedulerJobService schedulerJobService = (SchedulerJobService)SpringUtil.getBean(seriveName);
            schedulerJobService.callSync(bizId);

            log.info("===补偿成功==={}={}==", bizId, seriveName);

        }catch(Exception ex){
            log.error("事务补偿失败", ex);
            //更新异常原因到队列表
            String reason = ex.getMessage();

            if(StringUtils.isNotEmpty(reason) && reason.length() > 500){
                reason = reason.substring(0, 500);
            }
            systemSendQueueBO.setLastFailReason(reason);

            systemSendQueueBO.setSendStatus(BaseConstant.QueueSendStatus.SEND_FAIL);

            if(systemSendQueueBO.getSendNum().intValue() >= 10){
                systemSendQueueBO.setSendStatus(BaseConstant.QueueSendStatus.SEND_STOP);
            }
            /**
             * 如果业务通知终止当前队列，则改为停止.
             * 例外：获取指令发送队列失败
             */
            if(SystemSendQueueHelper.isFinishedCurrentQueue()){
                systemSendQueueBO.setSendStatus(BaseConstant.QueueSendStatus.SEND_STOP);
            }

            /**
             * 开启独立事务更新队列状态
             */
            systemSendQueueBOService.indepUpdateSysSendQueueBO(systemSendQueueBO);

            throw ex;
        }finally {
            //移除当前线程补偿点
            SystemSendQueueHelper.remove();
        }

        return true ;
    }

}
